
package server.life;


import client.*;
import client.inventory.Equip;
import client.inventory.Item;
import client.inventory.MapleInventoryType;
import client.skills.Skill;
import client.skills.SkillFactory;
import client.status.MonsterStatus;
import client.status.MonsterStatusEffect;
import client.status.NewMonsterStatusEffect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import configs.ServerConfig;
import constants.GameConstants;
import constants.ItemConstants;
import constants.SkillConstants;
import constants.skills.侠盗;
import constants.skills.双刀;
import constants.skills.火毒;
import constants.skills.隐士;
import handling.channel.ChannelServer;
import handling.world.party.MapleParty;
import handling.world.party.MaplePartyCharacter;
import io.netty.util.concurrent.ScheduledFuture;
import scripting.event.EventInstanceManager;
import server.MapleItemInformationProvider;
import server.MapleStatEffect;
import server.MapleStatEffectFactory;
import server.Timer.EtcTimer;
import server.maps.MapleFoothold;
import server.maps.MapleMap;
import server.maps.MapleMapObject;
import server.maps.MapleMapObjectType;
import tools.ConcurrentEnumMap;
import tools.MaplePacketCreator;
import tools.Pair;
import tools.Randomizer;
import tools.packet.BuffPacket;
import tools.packet.MobPacket;

import java.awt.*;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;


















































 public class MapleMonster extends AbstractLoadedMapleLife {
    /*   53 */   private final Collection<AttackerEntry> attackers = new LinkedList<>();
    /*   54 */   private final ConcurrentEnumMap<MonsterStatus, MonsterStatusEffect> mobEffects = new ConcurrentEnumMap(MonsterStatus.class);
    /*   55 */   private final Map<Integer, List<Pair<MonsterStatus, NewMonsterStatusEffect>>> newMobEffects = new HashMap<>();
    /*   56 */   private final LinkedList<MonsterStatusEffect> poisonEffects = new LinkedList<>();
    /*   57 */   private final ReentrantReadWriteLock poisonsLock = new ReentrantReadWriteLock();
    /*   58 */   private final Map<Pair<Integer, Integer>, Integer> skillsUsed = new HashMap<>();
    /*   59 */   private final ReentrantReadWriteLock updateNewMobEffestLock = new ReentrantReadWriteLock();
    /*   60 */   private final Map<String, Integer> aggroRank = new HashMap<>();

       private Map<Pair<Integer, Integer>, Long> usedSkills;
       private MapleMonsterStats stats;
    /*   64 */   private ChangeableStats ostats = null;
    private long hp;
    /*   65 */   private long nextKill = 0L;
    private long lastDropTime = 0L;
    private long lastUpdateController = 0L;
       private int mp;
    /*   67 */   private byte carnivalTeam = -1;
       private MapleMap map;
    /*   69 */   private WeakReference<MapleMonster> sponge = new WeakReference<>(null);
    /*   70 */   private int linkoid = 0;
    private int lastNode = -1;
    private int highestDamageChar = 0;
    private int linkCID = 0;
    /*   71 */   private WeakReference<MapleCharacter> controller = new WeakReference<>(null);
    private boolean fake = false;
    private boolean dropsDisabled = false;
    private boolean controllerHasAggro = false;
    private boolean controllerKnowsAboutAggro;
       private boolean spawnRevivesDisabled = false;
       private EventInstanceManager eventInstance;
    /*   74 */   private MonsterListener listener = null;
    /*   75 */   private byte[] reflectpack = null;
    private byte[] nodepack = null;
    /*   76 */   private ScheduledFuture deadBound = null;
    /*   77 */   private int stolen = -1;
    private boolean shouldDropItem = false;
       private boolean killed = false;
    /*   79 */   private long changeTime = 0L;
    /*   80 */   private int reduceDamageType = -1;
       private int followChrID;
    /*   82 */   private int beadJade = 0;
    /*   83 */   private int eliteGrade = -1;
       private boolean isElite = false;
    /*   85 */   private int monsterType = -1;
       private int eliteType;
       private long lastMove;
       private List<Rectangle> rectangles;
    /*   89 */   private int transid = -1;
    /*   90 */   private int spawnTransTime = 0;
    /*   91 */   private int triangulation = 0;
       private int patrolScopeX1;
       private int patrolScopeX2;
    /*   94 */   private int nextSkill = 0;

    /*   96 */   private int nextSkillLevel = 0;




    @JsonCreator
     public MapleMonster(@JsonProperty("id") int id, @JsonProperty("stats") MapleMonsterStats stats) {
        /*  101 */
        super(id);
        /*  102 */
        initWithStats(stats);

    }



    public MapleMonster(MapleMonster monster) {
        /*  106 */
        super(monster);
        /*  107 */
        initWithStats(monster.stats);

    }



    public void initWithStats(MapleMonsterStats stats) {
        /*  111 */
        setStance(5);
        /*  112 */
        this.stats = stats;
        /*  113 */
        this.hp = stats.getHp();
        /*  114 */
        this.mp = stats.getMp();

        /*  116 */
        if (stats.getNoSkills() > 0) {
            /*  117 */
            this.usedSkills = new HashMap<>();

        }

    }



    public ArrayList<AttackerEntry> getAttackers() {
        /*  122 */
        if (this.attackers == null || this.attackers.size() <= 0) {
            /*  123 */
            return new ArrayList<>();

        }
        /*  125 */
        ArrayList<AttackerEntry> ret = new ArrayList<>();
        /*  126 */
        for (AttackerEntry e : this.attackers) {
            /*  127 */
            if (e != null) {
                /*  128 */
                ret.add(e);

            }

        }
        /*  131 */
        return ret;

    }



    public MapleMonsterStats getStats() {
        /*  135 */
        return this.stats;

    }



    public boolean isBoss() {
        /*  139 */
        return (this.stats.isBoss() || getEliteGrade() > 0);

    }



    public int getAnimationTime(String name) {
        /*  143 */
        return this.stats.getAnimationTime(name);

    }



    public void disableDrops() {
        /*  147 */
        this.dropsDisabled = true;

    }



    public boolean dropsDisabled() {
        /*  151 */
        return this.dropsDisabled;

    }



    public final void disableSpawnRevives() {
        /*  155 */
        this.spawnRevivesDisabled = true;

    }



    public final boolean spawnRevivesDisabled() {
        /*  159 */
        return this.spawnRevivesDisabled;

    }



    public final Map<String, Integer> getHitParts() {
        /*  163 */
        return this.stats.getHitParts();

    }



    public int getMobLevel() {
        /*  167 */
        if (this.ostats != null) {
            /*  168 */
            return this.ostats.level;

        }
        /*  170 */
        return this.stats.getLevel();

    }



    public long getHp() {
        /*  174 */
        return this.hp;

    }



    public void setHp(long hp) {
        /*  178 */
        this.hp = hp;

    }



    public ChangeableStats getChangedStats() {
        /*  182 */
        return this.ostats;

    }



    public long getMobMaxHp() {
        /*  186 */
        if (this.ostats != null) {
            /*  187 */
            return this.ostats.hp;

        }
        /*  189 */
        return this.stats.getHp();

    }



    public int getMp() {
        /*  193 */
        return this.mp;

    }



    public void setMp(int mp) {
        /*  197 */
        if (mp < 0) {
            /*  198 */
            mp = 0;

        }
        /*  200 */
        this.mp = mp;

    }



    public int getMobMaxMp() {
        /*  204 */
        if (this.ostats != null) {
            /*  205 */
            return this.ostats.mp;

        }
        /*  207 */
        return this.stats.getMp();

    }



    public int getMobExp() {
        /*  211 */
        if (this.ostats != null) {
            /*  212 */
            return this.ostats.exp;

        }
        /*  214 */
        return this.stats.getExp();

    }



    public void setNextSkill(int i) {
        /*  218 */
        this.nextSkill = i;
        /*  219 */
        if (i == 0) {
            /*  220 */
            this.nextSkillLevel = i;

        }

    }



    public void setNextSkillLvl(int i) {
        /*  225 */
        this.nextSkillLevel = i;

    }



    public int getNextSkill() {
        /*  229 */
        return this.nextSkill;

    }



    public int getNextSkillLvl() {
        /*  233 */
        return this.nextSkillLevel;

    }








    public int getMobExpFromChannel() {
        /*  242 */
        return Math.min(2147483647, getMobExp() * ChannelServer.getInstance(this.map.getChannel()).getExpRate());

    }



    public void setOverrideStats(OverrideMonsterStats ostats) {
        /*  246 */
        this.ostats = new ChangeableStats(this.stats, ostats);
        /*  247 */
        this.hp = ostats.getHp();
        /*  248 */
        this.mp = ostats.getMp();

    }



    public void changeLevel(int newLevel) {
        /*  252 */
        changeLevel(newLevel, true);

    }



    public void changeLevel(int newLevel, boolean pqMob) {
        /*  256 */
        this.ostats = new ChangeableStats(this.stats, newLevel, pqMob);
        /*  257 */
        this.hp = this.ostats.getHp();
        /*  258 */
        this.mp = this.ostats.getMp();

    }



    public void changeLevelmod(int newLevel, int multipler) {
        /*  262 */
        this.ostats = new ChangeableStats(this.stats, newLevel, multipler);
        /*  263 */
        this.hp = this.ostats.getHp();
        /*  264 */
        this.mp = this.ostats.getMp();

    }



    public MapleMonster getSponge() {
        /*  268 */
        return this.sponge.get();

    }



    public void setSponge(MapleMonster mob) {
        /*  272 */
        this.sponge = new WeakReference<>(mob);
        /*  273 */
        if (this.linkoid <= 0) {
            /*  274 */
            this.linkoid = mob.getObjectId();

        }

    }



    public void sendMobZone(int reduceDamageType) {
        /*  279 */
        getMap().broadcastMessage(MobPacket.showMonsterPhaseChange(getObjectId(), reduceDamageType), getTruePosition());
        /*  280 */
        getMap().broadcastMessage(MobPacket.changeMonsterZone(getObjectId(), reduceDamageType), getTruePosition());

    }



    public boolean damage(MapleCharacter from, long damage, boolean updateAttackTime) {
        /*  284 */
        return damage(from, damage, updateAttackTime, 0);

    }


    public boolean damage(MapleCharacter from, long damage, boolean updateAttackTime, int lastSkill) {

        AttackerEntry attacker;
        /*  288 */
        if (ServerConfig.DEBUG_MODE &&
                /*  289 */       from.isAdmin()) {
            /*  290 */
            from.dropDebugMessage(1, "[怪物掉血]：" + damage);

        }

        /*  293 */
        if (from == null || damage <= 0L || !isAlive()) {
            /*  294 */
            return false;

        }

        /*  297 */
        if (from.getParty() != null) {
            /*  298 */
            attacker = new PartyAttackerEntry(from.getParty().getPartyId());

        } else {
            /*  300 */
            attacker = new SingleAttackerEntry(from);

        }
        /*  302 */
        boolean replaced = false;
        /*  303 */
        boolean killmob = false;
        /*  304 */
        for (AttackerEntry aentry : getAttackers()) {
            /*  305 */
            if (aentry != null && aentry.equals(attacker)) {
                /*  306 */
                attacker = aentry;
                /*  307 */
                replaced = true;

                break;

            }

        }
        /*  311 */
        if (!replaced) {
            /*  312 */
            this.attackers.add(attacker);

        }
        /*  314 */
        long rDamage = Math.max(0L, Math.min(damage, this.hp));
        /*  315 */
        attacker.addDamage(from, rDamage, updateAttackTime);

        /*  317 */
        if (this.stats.getSelfD() != -1) {
            /*  318 */
            this.hp -= rDamage;
            /*  319 */
            if (this.hp > 0L) {
                /*  320 */
                if (this.hp < this.stats.getSelfDHp()) {
                    /*  321 */
                    this.map.killMonster(this, from, false, false, this.stats.getSelfD(), lastSkill);

                } else {
                    /*  323 */
                    for (AttackerEntry mattacker : getAttackers()) {
                        /*  324 */
                        for (AttackingMapleCharacter cattacker : mattacker.getAttackers()) {
                            /*  325 */
                            if (cattacker.getAttacker().getMap() == from.getMap() &&
                                    /*  326 */                 cattacker.getLastAttackTime() >= System.currentTimeMillis() - 4000L) {
                                /*  327 */
                                cattacker.getAttacker().getClient().announce(MobPacket.showMonsterHP(getObjectId(), getHPPercent()));

                            }

                        }

                    }

                }

            } else {

                /*  334 */
                this.map.killMonster(this, from, true, false, (byte) 1, lastSkill);
                /*  335 */
                killmob = true;

            }

        } else {
            /*  338 */
            if (this.sponge.get() != null)
                 {
                /*  340 */
                if (((MapleMonster) this.sponge.get()).hp > 0L) {


                    /*  343 */
                    ((MapleMonster) this.sponge.get()).hp -= rDamage;
                    /*  344 */
                    if (((MapleMonster) this.sponge.get()).hp <= 0L) {
                        /*  345 */
                        this.map.broadcastMessage(MobPacket.showBossHP(((MapleMonster) this.sponge.get()).getId(), -1L, ((MapleMonster) this.sponge.get()).getMobMaxHp()));
                        /*  346 */
                        this.map.killMonster(this.sponge.get(), from, true, false, (byte) 1, lastSkill);

                    } else {
                        /*  348 */
                        this.map.broadcastMessage(MobPacket.showBossHP(this.sponge.get()));

                    }

                }

            }
            /*  352 */
            if (this.hp > 0L) {
                /*  353 */
                this.hp -= rDamage;
                /*  354 */
                if (this.eventInstance != null) {

                    /*  356 */
                    this.eventInstance.monsterDamaged(from, this, rDamage);

                } else {
                    /*  358 */
                    EventInstanceManager em = from.getEventInstance();
                    /*  359 */
                    if (em != null)
                         {
                        /*  361 */
                        em.monsterDamaged(from, this, rDamage);

                    }

                }
                /*  364 */
                if (this.sponge.get() == null && this.hp > 0L) {
                    /*  365 */
                    switch (this.stats.getHPDisplayType()) {

                        case 0:
                            /*  367 */
                            this.map.broadcastMessage(MobPacket.showBossHP(this), getTruePosition());

                            break;

                        case 1:
                            /*  370 */
                            this.map.broadcastMessage(from, MobPacket.damageFriendlyMob(this, damage, true), false);

                            break;

                        case 2:
                            /*  373 */
                            this.map.broadcastMessage(MobPacket.showMonsterHP(getObjectId(), getHPPercent()));
                            /*  374 */
                            from.mulung_EnergyModify(true);

                            break;

                        case 3:
                            /*  377 */
                            for (AttackerEntry mattacker : getAttackers()) {
                                /*  378 */
                                if (mattacker != null) {
                                    /*  379 */
                                    for (AttackingMapleCharacter cattacker : mattacker.getAttackers()) {
                                        /*  380 */
                                        if (cattacker != null && cattacker.getAttacker().getMap() == from.getMap() &&
                                                /*  381 */                       cattacker.getLastAttackTime() >= System.currentTimeMillis() - 4000L) {
                                            /*  382 */
                                            cattacker.getAttacker().getClient().announce(MobPacket.showMonsterHP(getObjectId(), getHPPercent()));

                                        }

                                    }

                                }

                            }

                            break;

                    }


                }
                /*  391 */
                if (getEventInstance() != null && (getEventInstance().getName().equals("BossMagnus_EASY") || getEventInstance().getName().equals("BossMagnus_NORMAL") || getEventInstance().getName().equals("BossMagnus_HARD"))) {
                    /*  392 */
                    int reduceDamageType = (int) (getStats().getMobZone().size() - Math.ceil((this.hp / getMobMaxHp() * getStats().getMobZone().size()))) + 1;
                    /*  393 */
                    if (Integer.valueOf(getEventInstance().getProperty("HPstate")).intValue() < reduceDamageType) {
                        /*  394 */
                        getEventInstance().setProperty("HPstate", String.valueOf(reduceDamageType));
                        /*  395 */
                        setReduceDamageType(reduceDamageType);
                        /*  396 */
                        sendMobZone(reduceDamageType);

                    }

                }
                /*  399 */
                if (this.hp <= 0L) {
                    /*  400 */
                    if (this.stats.getHPDisplayType() == 0) {
                        /*  401 */
                        this.map.broadcastMessage(MobPacket.showBossHP(getId(), -1L, getMobMaxHp()), getTruePosition());

                    }
                    /*  403 */
                    from.beforeKillMonster(getObjectId(), lastSkill);
                    /*  404 */
                    this.map.killMonster(this, from, true, false, (byte) 1, lastSkill);
                    /*  405 */
                    killmob = true;

                }

            }

        }
        /*  409 */
        startDropItemSchedule();
        /*  410 */
        return killmob;

    }



    public int getHPPercent() {
        /*  414 */
        return (int) Math.ceil(this.hp * 100.0D / getMobMaxHp());

    }



    public void heal(int hp, int mp, boolean broadcast) {
        /*  418 */
        long TotalHP = getHp() + hp;
        /*  419 */
        int TotalMP = getMp() + mp;
        /*  420 */
        if (TotalHP >= getMobMaxHp()) {
            /*  421 */
            setHp(getMobMaxHp());

        } else {
            /*  423 */
            setHp(TotalHP);

        }
        /*  425 */
        if (TotalMP >= getMp()) {
            /*  426 */
            setMp(getMp());

        } else {
            /*  428 */
            setMp(TotalMP);

        }
        /*  430 */
        if (broadcast) {
            /*  431 */
            this.map.broadcastMessage(MobPacket.healMonster(getObjectId(), hp));
            /*  432 */
        } else if (this.sponge.get() != null) {
            /*  433 */
            ((MapleMonster) this.sponge.get()).hp += hp;

        }

    }



    public void killed() {
        /*  438 */
        if (this.listener != null) {
            /*  439 */
            this.listener.monsterKilled();

        }
        /*  441 */
        this.listener = null;
        /*  442 */
        if (this.deadBound != null) {
            /*  443 */
            this.deadBound.cancel(false);

        }
        /*  445 */
        this.deadBound = null;

    }



    private void giveExpToCharacter(MapleCharacter attacker, int exp, boolean highestDamage, int numExpSharers, int lastskillID) {
        /*  449 */
        if (highestDamage) {
            /*  450 */
            if (this.eventInstance != null) {
                /*  451 */
                this.eventInstance.monsterKilled(attacker, this);

            } else {
                /*  453 */
                EventInstanceManager em = attacker.getEventInstance();
                /*  454 */
                if (em != null) {
                    /*  455 */
                    em.monsterKilled(attacker, this);

                }

            }
            /*  458 */
            this.highestDamageChar = attacker.getId();

        }
        /*  460 */
        if (exp > 0 && attacker.isAlive()) {
            /*  461 */
            MonsterStatusEffect ms = (MonsterStatusEffect) this.mobEffects.get(MonsterStatus.MOB_STAT_Showdown);
            /*  462 */
            if (ms != null) {
                /*  463 */
                exp += (int) (exp * ms.getX().intValue() / 100.0D);

            }
            /*  465 */
            if (attacker.hasDisease(MapleDisease.诅咒)) {
                /*  466 */
                exp /= 2;

            }
            /*  468 */
            Integer holySymbol = attacker.getBuffedValue(MapleBuffStat.神圣祈祷);
            /*  469 */
            if (holySymbol != null) {
                /*  470 */
                exp = (int) (exp * (1.0D + holySymbol.doubleValue() / 100.0D));

            }

            /*  473 */
            exp = (int) Math.min(2.147483647E9D, exp * attacker.getEXPMod() * (attacker.getStat()).expBuff / 100.0D * ChannelServer.getInstance(this.map.getChannel()).getExpRate());

            /*  475 */
            attacker.getTrait(MapleTraitType.charisma).addExp(this.stats.getCharismaEXP(), attacker);

            /*  477 */
            attacker.gainExpMonster(exp, true, highestDamage, numExpSharers, this.stats.isPartyBonus(), this.stats.getPartyBonusRate());

        }
        /*  479 */
        attacker.mobKilled(getId(), lastskillID);

    }



    public void checkMobZone() {
        /*  483 */
        if (getEventInstance() != null && (getEventInstance().getName().equals("BossMagnus_EASY") || getEventInstance().getName().equals("BossMagnus_NORMAL") || getEventInstance().getName().equals("BossMagnus_HARD"))) {
            /*  484 */
            sendMobZone((int) (5.0D - Math.ceil((this.hp / getMobMaxHp()) * 4.0D)));

        }

    }




    public void checkMobZone(MapleCharacter player, boolean bl2) {
        /*  490 */
        if (player.getEventInstance() == null || (getId() != 8880010 && getId() != 8880002 && getId() != 8880000)) {

            return;

        }
        /*  493 */
        int hpstate = Integer.valueOf(player.getEventInstance().getProperty("HPstate")).intValue();
        /*  494 */
        int min = Math.min(hpstate, getStats().getMobZone().size());
        /*  495 */
        Rectangle rectangle = MapleStatEffectFactory.calculateBoundingBox(getPosition(), isFacingLeft(), (Point) ((Pair) getStats().getMobZone().get(min - 1)).getLeft(), (Point) ((Pair) getStats().getMobZone().get(min - 1)).getRight(), 0);
        /*  496 */
        List list = getMap().getCharactersIntersect(rectangle);
        /*  497 */
        double d2 = (!list.contains(player) && player.isAlive()) ? 0.05D : 0.01D, d3 = d2;
        /*  498 */
        if (!bl2) {
            /*  499 */
            if (list.contains(player) && hpstate < 3) {
                /*  500 */
                if (player.isAlive() && player.isAttclimit()) {
                    /*  501 */
                    player.setAttclimit(false);
                    /*  502 */
                    player.getClient().announce(BuffPacket.giveBuff(0, 0, Collections.singletonMap(MapleBuffStat.SECONDARY_STAT_MobZoneState, Integer.valueOf(getObjectId())), null, player));

                }
                /*  504 */
            } else if (!player.isAttclimit()) {
                /*  505 */
                player.setAttclimit(true);
                /*  506 */
                player.getClient().announce(BuffPacket.cancelBuff(Collections.singletonList(MapleBuffStat.SECONDARY_STAT_MobZoneState), player));

            }

        } else {
            /*  509 */
            player.addHPMP((int) (-player.getStat().getCurrentMaxHp() * d2), 0);

        }

    }



    public int killBy(MapleCharacter killer, int lastSkill) {
        /*  514 */
        if (this.killed) {
            /*  515 */
            return 1;

        }
        /*  517 */
        this.killed = true;
        /*  518 */
        int totalBaseExp = getMobExp();
        /*  519 */
        AttackerEntry highest = null;
        /*  520 */
        long highdamage = 0L;
        /*  521 */
        List<AttackerEntry> list = getAttackers();
        /*  522 */
        for (AttackerEntry attackEntry : list) {
            /*  523 */
            if (attackEntry != null && attackEntry.getDamage() > highdamage) {
                /*  524 */
                highest = attackEntry;
                /*  525 */
                highdamage = attackEntry.getDamage();

            }

        }

        /*  529 */
        for (AttackerEntry attackEntry : list) {
            /*  530 */
            if (attackEntry != null) {
                /*  531 */
                int baseExp = (int) Math.ceil(totalBaseExp * attackEntry.getDamage() / getMobMaxHp());
                /*  532 */
                attackEntry.killedMob(getMap(), baseExp, (attackEntry == highest), lastSkill);

            }

        }
        /*  535 */
        MapleCharacter controll = this.controller.get();
        /*  536 */
        if (controll != null) {
            /*  537 */
            controll.getClient().announce(MobPacket.stopControllingMonster(getObjectId()));
            /*  538 */
            controll.stopControllingMonster(this);

        }
        /*  540 */
        int achievement = 0;
        /*  541 */
        switch (getId()) {

            case 9400121:
                /*  543 */
                achievement = 12;

                break;

            case 8500002:
                /*  546 */
                achievement = 13;

                break;

            case 8510000:

            case 8520000:
                /*  550 */
                achievement = 14;

                break;

        }


        /*  555 */
        if (achievement != 0) {
            /*  556 */
            if (killer != null && killer.getParty() != null) {
                /*  557 */
                for (MaplePartyCharacter pChar : killer.getParty().getMembers()) {
                    /*  558 */
                    MapleCharacter mpc = killer.getMap().getCharacterById(pChar.getId());
                    /*  559 */
                    if (mpc != null) {
                        /*  560 */
                        mpc.finishAchievement(achievement);

                    }

                }
                /*  563 */
            } else if (killer != null) {
                /*  564 */
                killer.finishAchievement(achievement);

            }

        }
        /*  567 */
        if (killer != null && isBoss()) {
            /*  568 */
            killer.finishAchievement(18);

        }


        /*  572 */
        spawnRevives(getMap());
        /*  573 */
        if (this.eventInstance != null) {
            /*  574 */
            this.eventInstance.monsterDrop(killer, this);

        }
        /*  576 */
        if (this.eventInstance != null) {
            /*  577 */
            this.eventInstance.unregisterMonster(this);
            /*  578 */
            this.eventInstance = null;

        }
        /*  580 */
        if (killer != null && killer.getPyramidSubway() != null) {
            /*  581 */
            killer.getPyramidSubway().onKill(killer);

        }
        /*  583 */
        this.hp = 0L;
        /*  584 */
        MapleMonster oldSponge = getSponge();
        /*  585 */
        this.sponge = new WeakReference<>(null);
        /*  586 */
        if (oldSponge != null && oldSponge.isAlive()) {
            /*  587 */
            boolean set = true;
            /*  588 */
            for (MapleMapObject mon : this.map.getAllMonstersThreadsafe()) {
                /*  589 */
                MapleMonster mons = (MapleMonster) mon;
                /*  590 */
                if (mons.isAlive() && mons.getObjectId() != oldSponge.getObjectId() && mons.getStats().getLevel() > 1 && mons.getObjectId() != getObjectId() && (mons.getSponge() == oldSponge || mons.getLinkOid() == oldSponge.getObjectId())) {
                    /*  591 */
                    set = false;

                    break;

                }

            }
            /*  595 */
            if (set) {
                /*  596 */
                this.map.killMonster(oldSponge, killer, true, false, (byte) 1);

            }

        }

        /*  600 */
        this.reflectpack = null;
        /*  601 */
        this.nodepack = null;
        /*  602 */
        if (this.mobEffects.size() > 0) {
            /*  603 */
            List<MonsterStatus> statuses = new LinkedList<>(this.mobEffects.keySet());
            /*  604 */
            for (MonsterStatus ms : statuses) {
                /*  605 */
                cancelStatus(ms);

            }
            /*  607 */
            statuses.clear();

        }
        /*  609 */
        if (this.poisonEffects.size() > 0) {
            /*  610 */
            List<MonsterStatusEffect> ps = new LinkedList<>();
            /*  611 */
            this.poisonsLock.readLock().lock();

            try {
                /*  613 */
                ps.addAll(this.poisonEffects);

            } finally {
                /*  615 */
                this.poisonsLock.readLock().unlock();

            }
            /*  617 */
            for (MonsterStatusEffect p : ps) {
                /*  618 */
                cancelSingleStatus(p);

            }
            /*  620 */
            ps.clear();

        }
        /*  622 */
        if (this.newMobEffects.size() > 0) {
            /*  623 */
            this.newMobEffects.clear();

        }


        /*  627 */
        cancelDropItem();
        /*  628 */
        int v1 = this.highestDamageChar;
        /*  629 */
        this.highestDamageChar = 0;
        /*  630 */
        return v1;
    }

    public void spawnRevives(MapleMap map) {
        Iterator<Integer> iterator1;
        MapleMonster linkMob;
        List<MapleMonster> cs_mobs;
        Iterator<Integer> iterator2;

        List<MapleMonster> mobs;

        Iterator<Integer> iterator3;
        Iterator<Integer> iterator5;

        MapleMonster linkMob_1;
        /*  634 */
        List<Integer> toSpawn = this.stats.getRevives();
        /*  635 */
        if (toSpawn == null || getLinkCID() > 0 || this.spawnRevivesDisabled) {

            return;

        }

        /*  639 */
        MapleMonster spongy = null;
        /*  640 */
        long spongyHp = 0L;


        /*  643 */
        switch (getId()) {

            case 6160003:

            case 8820213:

            case 8820214:

            case 8820215:

            case 8820216:

            case 8820217:

            case 8820218:

            case 8820219:

            case 8820220:

            case 8820221:

            case 8820222:

            case 8820223:

            case 8820224:

            case 8820226:

            case 8820227:

            case 8840000:

            case 8850011:

            case 8950000:

            case 8950001:

            case 8950100:

            case 8950101:

                return;

















            case 8810119:

            case 8810120:

            case 8810121:

            case 8810122:
                /*  686 */
                for (iterator1 = toSpawn.iterator(); iterator1.hasNext(); ) {
                    int i = ((Integer) iterator1.next()).intValue();
                    /*  687 */
                    MapleMonster mob = MapleLifeFactory.getMonster(i);
                    /*  688 */
                    mob.setPosition(getTruePosition());
                    /*  689 */
                    if (this.eventInstance != null) {
                        /*  690 */
                        this.eventInstance.registerMonster(mob);

                    }
                    /*  692 */
                    if (dropsDisabled()) {
                        /*  693 */
                        mob.disableDrops();

                    }
                    /*  695 */
                    switch (mob.getId()) {

                        case 8810119:

                        case 8810120:

                        case 8810121:

                        case 8810122:
                            /*  700 */
                            spongy = mob;

                    }

                }

                /*  704 */
                if (spongy != null && map.getMonsterById(spongy.getId()) == null) {
                    /*  705 */
                    map.spawnMonster(spongy, -2);
                    /*  706 */
                    for (MapleMapObject mon : map.getAllMonstersThreadsafe()) {
                        /*  707 */
                        MapleMonster mons = (MapleMonster) mon;
                        /*  708 */
                        if (mons.getObjectId() != spongy.getObjectId() && (mons.getSponge() == this || mons.getLinkOid() == getObjectId())) {
                            /*  709 */
                            mons.setSponge(spongy);

                        }

                    }

                }


            case 8820300:

            case 8820301:

            case 8820302:

            case 8820303:
                /*  718 */
                linkMob = MapleLifeFactory.getMonster(getId() - 190);
                /*  719 */
                if (linkMob != null) {
                    /*  720 */
                    toSpawn = linkMob.getStats().getRevives();

                }

            case 8820108:

            case 8820109:
                /*  724 */
                cs_mobs = new ArrayList<>();
                /*  725 */
                for (iterator2 = toSpawn.iterator(); iterator2.hasNext(); ) {
                    int i = ((Integer) iterator2.next()).intValue();
                    /*  726 */
                    MapleMonster mob = MapleLifeFactory.getMonster(i);
                    /*  727 */
                    mob.setPosition(getTruePosition());
                    /*  728 */
                    if (this.eventInstance != null) {
                        /*  729 */
                        this.eventInstance.registerMonster(mob);

                    }
                    /*  731 */
                    if (dropsDisabled()) {
                        /*  732 */
                        mob.disableDrops();

                    }
                    /*  734 */
                    switch (mob.getId()) {

                        case 8820109:

                        case 8820300:

                        case 8820301:

                        case 8820302:

                        case 8820303:

                        case 8820304:
                            /*  741 */
                            spongy = mob;

                            continue;

                    }

                    /*  745 */
                    if (mob.isFirstAttack()) {
                        /*  746 */
                        spongyHp += mob.getMobMaxHp();

                    }
                    /*  748 */
                    cs_mobs.add(mob);
                }




                /*  753 */
                if (spongy != null && map.getMonsterById(spongy.getId()) == null) {
                    /*  754 */
                    if (spongyHp > 0L) {
                        /*  755 */
                        spongy.setHp(spongyHp);
                        /*  756 */
                        spongy.getStats().setHp(spongyHp);

                    }

                    /*  759 */
                    map.spawnMonster(spongy, -2);
                    /*  760 */
                    for (MapleMonster i : cs_mobs) {
                        /*  761 */
                        map.spawnMonster(i, -2);
                        /*  762 */
                        i.setSponge(spongy);

                    }

                }





            case 8810026:

            case 8810130:

            case 8820002:

            case 8820003:

            case 8820004:

            case 8820005:

            case 8820006:

            case 8820008:

            case 8820009:

            case 8820010:

            case 8820011:

            case 8820012:

            case 8820013:

            case 8820102:

            case 8820103:

            case 8820104:

            case 8820105:

            case 8820106:
                /*  787 */
                mobs = new ArrayList<>();
                /*  788 */
                for (iterator3 = toSpawn.iterator(); iterator3.hasNext(); ) {
                    int i = ((Integer) iterator3.next()).intValue();
                    /*  789 */
                    MapleMonster mob = MapleLifeFactory.getMonster(i);
                    /*  790 */
                    mob.setPosition(getTruePosition());
                    /*  791 */
                    if (this.eventInstance != null) {
                        /*  792 */
                        this.eventInstance.registerMonster(mob);

                    }
                    /*  794 */
                    if (dropsDisabled()) {
                        /*  795 */
                        mob.disableDrops();

                    }
                    /*  797 */
                    switch (mob.getId()) {


                        case 8810018:

                        case 8810122:

                        case 8820009:

                        case 8820010:

                        case 8820011:

                        case 8820012:

                        case 8820013:

                        case 8820014:

                        case 8820019:

                        case 8820024:

                        case 8820025:

                        case 8820026:

                        case 8820027:
                            /*  812 */
                            spongy = mob;

                            continue;

                    }

                    /*  816 */
                    mobs.add(mob);
                }




                /*  821 */
                if (spongy != null && map.getMonsterById(spongy.getId()) == null) {

                    /*  823 */
                    map.spawnMonster(spongy, -2);
                    /*  824 */
                    for (MapleMonster i : mobs) {
                        /*  825 */
                        map.spawnMonster(i, -2);
                        /*  826 */
                        i.setSponge(spongy);

                    }

                }


            case 8820304:
                /*  831 */
                linkMob_1 = MapleLifeFactory.getMonster(getId() - 190);
                /*  832 */
                if (linkMob_1 != null) {
                    /*  833 */
                    toSpawn = linkMob_1.getStats().getRevives();

                }


            case 8820101:

            case 8820200:

            case 8820201:

            case 8820202:

            case 8820203:

            case 8820204:

            case 8820205:

            case 8820206:

            case 8820207:

            case 8820208:

            case 8820209:

            case 8820210:

            case 8820211:
                /*  849 */
                for (iterator5 = toSpawn.iterator(); iterator5.hasNext(); ) {
                    int i = ((Integer) iterator5.next()).intValue();
                    /*  850 */
                    MapleMonster mob = MapleLifeFactory.getMonster(i);
                    /*  851 */
                    if (this.eventInstance != null) {
                        /*  852 */
                        this.eventInstance.registerMonster(mob);

                    }
                    /*  854 */
                    mob.setPosition(getTruePosition());
                    /*  855 */
                    if (dropsDisabled()) {
                        /*  856 */
                        mob.disableDrops();

                    }
                    /*  858 */
                    map.spawnMonster(mob, -2);
                }


        }



        /*  864 */
        for (Iterator<Integer> iterator4 = toSpawn.iterator(); iterator4.hasNext(); ) {
            int i = ((Integer) iterator4.next()).intValue();
            /*  865 */
            MapleMonster mob = MapleLifeFactory.getMonster(i);
            /*  866 */
            if (mob == null) {

                continue;

            }
            /*  869 */
            if (this.eventInstance != null) {
                /*  870 */
                this.eventInstance.registerMonster(mob);

            }
            /*  872 */
            mob.setPosition(getTruePosition());
            /*  873 */
            if (dropsDisabled()) {
                /*  874 */
                mob.disableDrops();

            }
            /*  876 */
            map.spawnRevives(mob, getObjectId());
        }

    }











    public boolean isAlive() {
        /*  888 */
        return (this.hp > 0L);

    }



    public byte getCarnivalTeam() {
        /*  892 */
        return this.carnivalTeam;

    }



    public void setCarnivalTeam(byte team) {
        /*  896 */
        this.carnivalTeam = team;

    }



    public MapleCharacter getController() {
        /*  900 */
        return this.controller.get();

    }



    public void setController(MapleCharacter controller) {
        /*  904 */
        this.controller = new WeakReference<>(controller);

    }



    public boolean isAttackedBy(MapleCharacter chr) {
        /*  908 */
        for (AttackerEntry aentry : this.attackers) {
            /*  909 */
            if (aentry.contains(chr)) {
                /*  910 */
                return true;

            }

        }
        /*  913 */
        return false;

    }



    public boolean switchController(MapleCharacter newController, boolean immediateAggro) {
        /*  917 */
        this.lastUpdateController = System.currentTimeMillis();
        /*  918 */
        MapleCharacter controllers = getController();
        /*  919 */
        int type = 1;
        /*  920 */
        if (controllers != null && controllers == newController) {
            /*  921 */
            return false;

        }
        /*  923 */
        if (controllers != null) {
            /*  924 */
            type = 2;
            /*  925 */
            controllers.stopControllingMonster(this);

        }
        /*  927 */
        newController.controlMonster(this, immediateAggro, type);
        /*  928 */
        if (this.nodepack != null && !this.map.isLastNode(getLastNode())) {
            /*  929 */
            newController.send(this.nodepack);

        }
        /*  931 */
        changeAggroTip(newController);

        /*  933 */
        if (immediateAggro) {
            /*  934 */
            setControllerHasAggro(true);
            /*  935 */
            setControllerKnowsAboutAggro(false);

        }
        /*  937 */
        return true;

    }



    public void changeAggroTip(MapleCharacter newController) {
        /*  941 */
        StringBuilder sb = new StringBuilder();
        /*  942 */
        switch (getId()) {

            case 8850011:

            case 8880000:

            case 8880010:
                /*  946 */
                this.aggroRank.put(newController.getName(), Integer.valueOf(9999));
                /*  947 */
                newController.send_other(MobPacket.showMonsterNotice(getId(), 0, sb.append(getStats().getName()).append("把").append(newController.getName()).append("视作了最危险的敌人。").toString()), true);
                /*  948 */
                newController.getMap().broadcastMessage(MobPacket.getBossHatred(this.aggroRank));

                break;

        }

    }





    public boolean checkAggro(boolean bl2) {
        /*  956 */
        boolean bl4 = false;
        /*  957 */
        boolean bl5 = false;
        /*  958 */
        boolean bl3 = (System.currentTimeMillis() - this.lastUpdateController > 3000L), bl6 = bl3;
        /*  959 */
        if (bl3 && (!isControllerKnowsAboutAggro() || (bl2 && !getAggroRank().isEmpty()))) {
            /*  960 */
            MapleCharacter controller = getController();
            /*  961 */
            ArrayList<Map.Entry<String, Integer>> arrayList = new ArrayList<>(this.aggroRank.entrySet());
            /*  962 */
            arrayList.sort((entry, entry2) -> ((Integer) entry2.getValue()).intValue() - ((Integer) entry.getValue()).intValue());
            /*  963 */
            for (Map.Entry<String, Integer> entry3 : arrayList) {

                /*  965 */
                MapleCharacter newController = this.map.getCharacterByName(entry3.getKey());
                /*  966 */
                if (newController == null) {
                    /*  967 */
                    this.aggroRank.put(entry3.getKey(), Integer.valueOf(0));

                    continue;

                }
                /*  970 */
                boolean bl7 = (newController.getTruePosition().distanceSq(getTruePosition()) < 100000.0D);
                /*  971 */
                if (newController.isAlive() && getController() == newController && bl7) {
                    /*  972 */
                    bl4 = true;

                    continue;

                }
                /*  975 */
                if (!newController.isAlive() || bl4 || !bl7)
                    /*  976 */ continue;
                controller = this.map.getCharacterByName(entry3.getKey());
                /*  977 */
                bl4 = true;

            }
            /*  979 */
            if (controller != null && controller != getController()) {
                /*  980 */
                bl5 = switchController(controller, true);

            }

        }
        /*  983 */
        return bl5;

    }



    public boolean checkTrans(MapleCharacter player) {
        /*  987 */
        MapleMonsterStats.TransMobs transMobs = getStats().getTransMobs();
        /*  988 */
        MapleMonster monster = null;
        /*  989 */
        int n2 = -1;
        /*  990 */
        boolean bl2 = true;
        /*  991 */
        long l2 = System.currentTimeMillis();
        /*  992 */
        if ((transMobs != null && System.currentTimeMillis() > getChangeTime() + (transMobs.getCooltime() * 1000)) || this.transid > 0) {

            /*  994 */
            if (transMobs != null && transMobs.getHpTriggerOff() < getHPPercent() && getHPPercent() <= transMobs.getHpTriggerOn() && this.transid <= 0) {
                /*  995 */
                int mobid;
                if (transMobs.getWithMob() <= 0) {
                    /*  996 */
                    mobid = ((Integer) transMobs.getMobids().get(Randomizer.nextInt(transMobs.getMobids().size()))).intValue();
                    /*  997 */
                    n2 = getId();
                    /*  998 */
                } else if (player.getMap().getMonsterById(transMobs.getWithMob()) == null) {
                    /*  999 */
                    mobid = transMobs.getWithMob();
                    /* 1000 */
                    bl2 = false;
                    /* 1001 */
                    l2 = 0L;

                } else {
                    /* 1003 */
                    return false;

                }

                try {
                    /* 1006 */
                    monster = MapleLifeFactory.getMonster(mobid);
                    /* 1007 */
                    if (monster != null) {
                        /* 1008 */
                        monster.spawnTransTime = transMobs.getTime() * 1000;

                    }
                    /* 1010 */
                } catch (RuntimeException runtimeException) {
                    /* 1011 */
                    System.out.println("checkTrans 召唤怪物失败\r\n" + runtimeException);

                }
                /* 1013 */
            } else if (this.transid > 0 && System.currentTimeMillis() > getChangeTime() + this.spawnTransTime) {

                try {
                    /* 1015 */
                    monster = MapleLifeFactory.getMonster(this.transid);
                    /* 1016 */
                } catch (RuntimeException runtimeException) {
                    /* 1017 */
                    System.out.println("checkTrans 召唤回原怪物失败\r\n" + runtimeException);

                }

            }
            /* 1020 */
            if (monster != null) {
                /* 1021 */
                monster.transid = n2;
                /* 1022 */
                monster.setPosition(getTruePosition());
                /* 1023 */
                monster.setChangeTime(l2);
                /* 1024 */
                if (getChangedStats() != null) {
                    /* 1025 */
                    monster.setOverrideStats(getChangedStats());

                }
                /* 1027 */
                monster.setStance(getStance());
                /* 1028 */
                monster.setFh(getFh());
                /* 1029 */
                monster.setHp(getHp());
                /* 1030 */
                if (transMobs != null) {
                    /* 1031 */
                    Pair<Integer, Integer> skillPair = transMobs.getSkills().get(Randomizer.nextInt(transMobs.getSkills().size()));
                    /* 1032 */
                    MobSkill mobSkill = MobSkillFactory.getMobSkill(((Integer) skillPair.getLeft()).intValue(), ((Integer) skillPair.getRight()).intValue());
                    /* 1033 */
                    if (mobSkill != null) {
                        /* 1034 */
                        mobSkill.applyEffect(player, this, 0, true);

                    }

                }
                /* 1037 */
                if (player.getEventInstance() != null) {
                    /* 1038 */
                    player.getEventInstance().registerMonster(monster);

                }
                /* 1040 */
                player.getMap().spawnMonsterWithEffect(monster, -2, new Point((getTruePosition()).x, (getTruePosition()).y - 1));
                /* 1041 */
                monster.handleDeadBound(2);
                /* 1042 */
                if (bl2) {
                    /* 1043 */
                    player.getMap().removeMonster(this);
                    /* 1044 */
                    player.getEventInstance().unregisterMonster(this);

                }
                /* 1046 */
                return bl2;

            }

        }
        /* 1049 */
        return false;

    }



    public void addListener(MonsterListener listener) {
        /* 1053 */
        this.listener = listener;

    }



    public boolean isControllerHasAggro() {
        /* 1057 */
        return this.controllerHasAggro;

    }



    public void setControllerHasAggro(boolean controllerHasAggro) {
        /* 1061 */
        this.controllerHasAggro = controllerHasAggro;

    }






    public boolean isControllerKnowsAboutAggro() {
        /* 1068 */
        return this.controllerKnowsAboutAggro;

    }






    public void setControllerKnowsAboutAggro(boolean controllerKnowsAboutAggro) {
        /* 1075 */
        this.controllerKnowsAboutAggro = controllerKnowsAboutAggro;

    }



    public long getChangeTime() {
        /* 1079 */
        return this.changeTime;

    }



    public void setChangeTime(long changeTime) {
        /* 1083 */
        this.changeTime = changeTime;

    }



    public int getReduceDamageType() {
        /* 1087 */
        return this.reduceDamageType;

    }



    public void setReduceDamageType(int reduceDamageType) {
        /* 1091 */
        this.reduceDamageType = reduceDamageType;

    }



    public int getFollowChrID() {
        /* 1095 */
        return this.followChrID;

    }



    public void setFollowChrID(int followChrID) {
        /* 1099 */
        this.followChrID = followChrID;

    }



    public int getBeadJade() {
        /* 1103 */
        return this.beadJade;

    }



    public void setBeadJade(int beadJade) {
        /* 1107 */
        this.beadJade = beadJade;

    }



    public int getEliteGrade() {
        /* 1111 */
        return this.eliteGrade;

    }



    public void setEliteGrade(int eliteGrade) {
        /* 1115 */
        this.eliteGrade = eliteGrade;

    }



    public int getEliteType() {
        /* 1119 */
        return this.eliteType;

    }



    public void setEliteType(int eliteType) {
        /* 1123 */
        this.eliteType = eliteType;

    }



























    public void sendStatus(MapleClient client) {
        /* 1151 */
        if (ServerConfig.CHANNEL_APPLYMONSTERSTATUS) {

            return;

        }
        /* 1154 */
        if (this.reflectpack != null) {
            /* 1155 */
            client.announce(this.reflectpack);

        }

    }




    public void sendSpawnData(MapleClient client) {
        /* 1161 */
        if (!isAlive()) {

            return;

        }
        /* 1164 */
        client.announce(MobPacket.spawnMonster(this, (this.fake && this.linkCID <= 0) ? -4 : -1, 0));
        /* 1165 */
        sendStatus(client);
        /* 1166 */
        if (this.map != null && !this.stats.isEscort() && client.getPlayer() != null && client.getPlayer().getTruePosition().distanceSq(getTruePosition()) <= GameConstants.maxViewRangeSq_Half().doubleValue()) {
            /* 1167 */
            this.map.updateMonsterController(this);

        }
        /* 1169 */
        if (getEventInstance() != null && (getEventInstance().getName().equals("BossMagnus_EASY") || getEventInstance().getName().equals("BossMagnus_NORMAL") || getEventInstance().getName().equals("BossMagnus_HARD"))) {
            /* 1170 */
            sendMobZone((int) (5.0D - Math.ceil((this.hp / getMobMaxHp()) * 4.0D)));
            /* 1171 */
            client.announce(MobPacket.getBossHatred(this.aggroRank));

        }
        /* 1173 */
        if (getReduceDamageType() > 0) {
            /* 1174 */
            client.announce(MobPacket.showMonsterPhaseChange(getObjectId(), getReduceDamageType()));

        }

    }




    public void sendDestroyData(MapleClient client) {
        /* 1180 */
        if (this.stats.isEscort() && getEventInstance() != null && this.lastNode >= 0) {
            /* 1181 */
            this.map.resetShammos(client);

        } else {
            /* 1183 */
            if (getController() != null && client.getPlayer() != null && client.getPlayer().getId() == getController().getId()) {
                /* 1184 */
                client.getPlayer().stopControllingMonster(this);
                /* 1185 */
                client.announce(MobPacket.stopControllingMonster(getObjectId()));
                /* 1186 */
                setController((MapleCharacter) null);
                /* 1187 */
                setControllerHasAggro(false);

            }
            /* 1189 */
            client.announce(MobPacket.killMonster(getObjectId(), 0));

        }

    }




    public String toString() {
        /* 1195 */
        StringBuilder sb = new StringBuilder();

        /* 1197 */
        sb.append(this.stats.getName());
        /* 1198 */
        sb.append("(");
        /* 1199 */
        sb.append(getId());
        /* 1200 */
        sb.append(") 等级:");
        /* 1201 */
        sb.append(this.stats.getLevel());
        /* 1202 */
        if (this.ostats != null) {
            /* 1203 */
            sb.append("→");
            /* 1204 */
            sb.append(this.ostats.level);

        }
        /* 1206 */
        sb.append(" 坐标(X:");
        /* 1207 */
        sb.append((getTruePosition()).x);
        /* 1208 */
        sb.append("/Y:");
        /* 1209 */
        sb.append((getTruePosition()).y);
        /* 1210 */
        sb.append(") 信息: ");
        /* 1211 */
        sb.append(getHp());
        /* 1212 */
        sb.append("/");
        /* 1213 */
        sb.append(getMobMaxHp());
        /* 1214 */
        sb.append("Hp, ");
        /* 1215 */
        sb.append(getMp());
        /* 1216 */
        sb.append("/");
        /* 1217 */
        sb.append(getMobMaxMp());
        /* 1218 */
        sb.append("Mp, oid: ");
        /* 1219 */
        sb.append(getObjectId());
        /* 1220 */
        sb.append("||仇恨目标: ");
        /* 1221 */
        MapleCharacter chr = this.controller.get();
        /* 1222 */
        sb.append((chr != null) ? chr.getName() : "无");
        /* 1223 */
        return sb.toString();

    }




    public MapleMapObjectType getType() {
        /* 1228 */
        return MapleMapObjectType.MONSTER;

    }



    public EventInstanceManager getEventInstance() {
        /* 1232 */
        return this.eventInstance;

    }



    public void setEventInstance(EventInstanceManager eventInstance) {
        /* 1236 */
        this.eventInstance = eventInstance;

    }



    public boolean isMobile() {
        /* 1240 */
        return this.stats.isMobile();

    }






    public int getStatusSourceID(MonsterStatus status) {
        /* 1247 */
        if (status == MonsterStatus.MOB_STAT_Poison) {
            /* 1248 */
            this.poisonsLock.readLock().lock();

            try {
                /* 1250 */
                for (MonsterStatusEffect ps : this.poisonEffects) {
                    /* 1251 */
                    if (ps != null) {
                        /* 1252 */
                        return ps.getSkill();

                    }

                }
                /* 1255 */
                return -1;

            } finally {
                /* 1257 */
                this.poisonsLock.readLock().unlock();

            }

        }
        /* 1260 */
        MonsterStatusEffect effect = (MonsterStatusEffect) this.mobEffects.get(status);
        /* 1261 */
        if (effect != null) {
            /* 1262 */
            return effect.getSkill();

        }
        /* 1264 */
        return -1;

    }



    public ElementalEffectiveness getEffectiveness(Element e) {
        /* 1268 */
        if (this.mobEffects.size() > 0 && this.mobEffects.containsKey(MonsterStatus.MOB_STAT_Venom_2)) {
            /* 1269 */
            return ElementalEffectiveness.正常;

        }
        /* 1271 */
        return this.stats.getEffectiveness(e);

    }



    public Map<Integer, List<Pair<MonsterStatus, NewMonsterStatusEffect>>> getNewMobEffects() {
        /* 1275 */
        return this.newMobEffects;

    }



    public void applyNewStatus(MapleStatEffect effect) {
        Map<MonsterStatus, Integer> monsterStati = effect.getMonsterStati();
        List<Pair<MonsterStatus, NewMonsterStatusEffect>> collect;
        updateNewMobEffestLock.writeLock().lock();
        try {
            if (monsterStati.size() > 0) {
                int d = Math.max(3, effect.getDOTTime());
                collect = monsterStati.entrySet().stream().map(entry -> new Pair<>(entry.getKey(), new NewMonsterStatusEffect(effect.getSourceid(), d, entry.getValue(), System.currentTimeMillis()))).collect(Collectors.toList());
                if (!newMobEffects.containsKey(effect.getSourceid())) {
                    map.broadcastMessage(MobPacket.applyNewMonsterStatus(this, collect));
                }
                newMobEffects.put(effect.getSourceid(), collect);
            }
        } finally {
            updateNewMobEffestLock.writeLock().unlock();
        }
    }





    public void cancelNewStatus(int skillid) {

        updateNewMobEffestLock.writeLock().lock();
        try {
            if (newMobEffects.containsKey(skillid)) {
                map.broadcastMessage(MobPacket.cancelMonsterStatus(getObjectId(), newMobEffects.get(skillid).stream().map(Pair::getLeft).collect(Collectors.toList())));
                newMobEffects.remove(skillid);
            }
        } finally {
            updateNewMobEffestLock.writeLock().unlock();
        }
    }



    public void applyStatus(MapleCharacter from, MonsterStatusEffect status, boolean poison, long duration, boolean checkboss, MapleStatEffect effect) {
        /* 1312 */
        List<MonsterStatusEffect> arrayList = new ArrayList<>();
        /* 1313 */
        arrayList.add(status);
        /* 1314 */
        applyStatus(from, arrayList, poison, duration, checkboss, effect);

    }



    public void applyStatus(MapleCharacter from, EnumMap<MonsterStatus, Integer> map, boolean poison, long duration, boolean checkboss, MapleStatEffect effect) {
        /* 1318 */
        ArrayList<MonsterStatusEffect> statuss = new ArrayList<>();
        /* 1319 */
        for (Map.Entry<MonsterStatus, Integer> entry : map.entrySet()) {
            /* 1320 */
            if (entry.getKey() == MonsterStatus.MOB_STAT_AddDamSkil && ((Integer) entry.getValue()).intValue() == 23121003) {
                /* 1321 */
                entry.setValue(Integer.valueOf(23121000));

            }
            /* 1323 */
            MonsterStatusEffect status = new MonsterStatusEffect(entry.getKey(), entry.getValue(), effect.getSourceid(), null, false);
            /* 1324 */
            if (MBuffcount(effect.getSourceid(), entry.getKey())) {
                /* 1325 */
                status.setCannotCancel(true);
                /* 1326 */
                if (((MonsterStatusEffect) this.mobEffects.get(entry.getKey())).getCount() < 3) {
                    /* 1327 */
                    status.setCount(((MonsterStatusEffect) this.mobEffects.get(entry.getKey())).getCount(), false);

                } else {

                    return;

                }

            }
            /* 1332 */
            statuss.add(status);

        }
        /* 1334 */
        applyStatus(from, statuss, poison, duration, checkboss, effect);

    }






    /*
     * 玩家给怪物上BUFF
     */
    public void applyStatus(MapleCharacter from, List<MonsterStatusEffect> statuss, boolean poison, long duration, boolean checkboss, MapleStatEffect effect) {
        if (!isAlive() || getLinkCID() > 0 || ServerConfig.CHANNEL_APPLYMONSTERSTATUS) {
            return;
        }
        MapleCharacter con = getController();
        List<MonsterStatusEffect> ret = new ArrayList<>();
        for (MonsterStatusEffect status : statuss) {
            Skill skilz = SkillFactory.getSkill(status.getSkill());
            if (skilz != null) {
                switch (stats.getEffectiveness(skilz.getElement())) {
                    case 免疫:
                    case 增强:
                        return;
                    case 正常:
                    case 虚弱:
                        break;
                    default:
                        return;
                }
            }
            // compos don't have an elemental (they have 2 - so we have to hack here...)
            int statusSkill = status.getSkill();
            switch (statusSkill) {
                case 2111006: { //火凤球 - 用火焰恶魔的火凤球同时攻击多个敌人。对象在一定时间内受到持续伤害。
                    switch (stats.getEffectiveness(Element.毒)) {
                        case 免疫:
                        case 增强:
                            return;
                    }
                    break;
                }
                case 2211006: { //冰凤球 - 用冰恶魔的冰碎片同时攻击多个敌人，使其冻结。对象在一定时间内受到持续伤害。
                    switch (stats.getEffectiveness(Element.冰)) {
                        case 免疫:
                        case 增强:
                            return;
                    }
                    break;
                }
                case 隐士.武器用毒液: //武器用毒液 - 永久性地在拳套上涂毒。有一定几率使对象中毒，持续受到毒素伤害。中毒效果无法重复，对象的HP不会下降到1以下。
                case 侠盗.武器用毒液:
                case 双刀.武器用毒液:
                case 隐士.致命毒液: //致命毒液 - 永久性地提高武器用毒液的中毒概率和毒素伤害，增加毒素重叠次数。
                case 侠盗.致命毒液:
                case 双刀.致命毒液: {
                    switch (stats.getEffectiveness(Element.毒)) {
                        case 免疫:
                        case 增强:
                            return;
                    }
                    break;
                }
            }
            MonsterStatus stat = status.getStati();
            if (stats.isNoDoom() && stat == MonsterStatus.MOB_STAT_Venom_2) {
                return;
            }
            if (isBoss()) {
                if (stat == MonsterStatus.MOB_STAT_Stun || stat == MonsterStatus.MOB_STAT_Speed) {
                    return;
                }
                if (checkboss && stat != (MonsterStatus.MOB_STAT_PAD) && stat != (MonsterStatus.MOB_STAT_Poison) && stat != (MonsterStatus.MOB_STAT_Blind) && stat != (MonsterStatus.MOB_STAT_MagicCrash)) {
                    return;
                }
                //hack: don't magic crash cygnus boss 希纳斯
                if (getId() == 8850011 && stat == MonsterStatus.MOB_STAT_MagicCrash) {
                    return;
                }
            }
            if (stats.isFriendly() || isFake()) {
                if (stat == MonsterStatus.MOB_STAT_Stun || stat == MonsterStatus.MOB_STAT_Speed || stat == MonsterStatus.MOB_STAT_Poison) {
                    return;
                }
            }
            if (effect == null) {
                return;
            }
            if (mobEffects.containsKey(stat)) {
                cancelStatus(stat);
            }
            if (stat == MonsterStatus.MOB_STAT_Poison) {
                poisonsLock.readLock().lock();
                try {
                    for (MonsterStatusEffect mse : poisonEffects) {
                        if (mse != null && (mse.getSkill() == effect.getSourceid() || mse.getSkill() == SkillConstants.getLinkedAttackSkill(effect.getSourceid()) || SkillConstants.getLinkedAttackSkill(mse.getSkill()) == effect.getSourceid())) {
                            return;
                        }
                    }
                } finally {
                    poisonsLock.readLock().unlock();
                }
            }
            if (poison && getHp() > 1) {
                if (statusSkill == 火毒.致命毒雾) {
                    duration = effect.getDOTTime() * 1000;
                } else {
                    duration = Math.max(duration, effect.getDOTTime() * 1000);
                }
                //System.out.println("中毒时间 - 默认: " + duration + " 技能: " + eff.getDOTTime() * 1000);
            }
            duration += from.getStat().dotTime * 1000; //有些被动技能增加 延长时间
            //System.out.println("中毒时间 - 被动加成: " + from.getStat().dotTime * 1000 + " 最终时间: " + duration);
            if (duration >= 60 * 1000) { //如果大于60秒 时间设置为 10秒中毒持续时间
                duration = 10 * 1000;
            }
            long aniTime = duration;
            status.setCancelTask(aniTime);
            if (poison && getHp() > 1) {
                status.setDotTime(duration); //设置中毒的持续时间
                int poisonDot = from.getStat().dot;
                int damageIncrease = from.getStat().getDamageIncrease(effect.getSourceid());
                if (damageIncrease > effect.getDOT()) {
                    poisonDot += damageIncrease;
                } else {
                    poisonDot += effect.getDOT();
                }
                if (from.isShowPacket()) {
                    from.dropDebugMessage(1, "[怪物DEBUFF] 中毒 技能ID: " + effect.getSourceid() + " 持续伤害:" + effect.getDOT() + " 被动:" + from.getStat().dot + " 被动加成:" + damageIncrease + " 最终加成:" + poisonDot);
                }
                status.setValue(status.getStati(), (int) (poisonDot * from.getStat().getCurrentMaxBaseDamage() / 100.0));
                int poisonDamage = (int) (aniTime / 1000 * status.getX() / 2);
                if (from.isShowPacket()) {
                    from.dropDebugMessage(1, "[怪物DEBUFF] 中毒伤害 中毒伤害: " + poisonDamage + " 持续时间: " + aniTime + " 持续伤害: " + status.getX());
                }
                status.setPoisonSchedule(poisonDamage, from);
                if (poisonDamage > 0) {
                    if (poisonDamage >= hp) {
                        poisonDamage = (int) (hp - 1);
                    }
                    damage(from, poisonDamage, false);
                }
            } else if (statusSkill == 隐士.影网术) {
                status.setValue(status.getStati(), (int) (getMobMaxHp() / 50.0 + 0.999));
                status.setPoisonSchedule(status.getX(), from);
            }
            if (stat == MonsterStatus.MOB_STAT_Poison || stat == MonsterStatus.MOB_STAT_Venom) {
                poisonsLock.writeLock().lock();
                try {
                    poisonEffects.add(status);
                } finally {
                    poisonsLock.writeLock().unlock();
                }
            }
            mobEffects.put(stat, status);
            ret.add(status);
        }
        if (con != null) {
            map.broadcastMessage(con, MobPacket.applyMonsterStatus(this, ret), getTruePosition());
            con.getClient().announce(MobPacket.applyMonsterStatus(this, ret));
        } else {
            map.broadcastMessage(MobPacket.applyMonsterStatus(this, ret), getTruePosition());
        }

    }




    public boolean hasSkillIdEffect(int skillid) {
        /* 1506 */
        for (Map.Entry<MonsterStatus, MonsterStatusEffect> effects : (Iterable<Map.Entry<MonsterStatus, MonsterStatusEffect>>) this.mobEffects.entrySet()) {
            /* 1507 */
            MonsterStatusEffect mse = effects.getValue();
            /* 1508 */
            if (mse.getSkill() == skillid) {
                /* 1509 */
                return true;

            }

        }
        /* 1512 */
        return false;

    }






    public void dispelSkill(MobSkill skillId) {
        /* 1519 */
        List<MonsterStatus> toCancel = new ArrayList<>();
        /* 1520 */
        for (Map.Entry<MonsterStatus, MonsterStatusEffect> effects : (Iterable<Map.Entry<MonsterStatus, MonsterStatusEffect>>) this.mobEffects.entrySet()) {
            /* 1521 */
            MonsterStatusEffect mse = effects.getValue();
            /* 1522 */
            if (mse.getMobSkill() != null && mse.getMobSkill().getSkillId() == skillId.getSkillId()) {
                /* 1523 */
                toCancel.add(effects.getKey());

            }

        }
        /* 1526 */
        for (MonsterStatus stat : toCancel) {
            /* 1527 */
            cancelStatus(stat);

        }

    }



    public boolean MBuffcount(int skillid, MonsterStatus monsterStatus) {
        /* 1532 */
        switch (skillid) {

            case 2321001:

            case 3120017:

            case 33000036:

            case 101110103:
                /* 1537 */
                return this.mobEffects.containsKey(monsterStatus);

        }

        /* 1540 */
        return (this.mobEffects.get(monsterStatus) != null && monsterStatus == MonsterStatus.MOB_STAT_Speed);

    }



    public void handleDeadBound(int type) {
        this.deadBound = (ScheduledFuture) EtcTimer.getInstance().register(() -> {
            List arrayList = new ArrayList();
            List arrayList2 = new ArrayList();
            if (this.getMap() != null) {
                this.getMap().getFootholds().getAllRelevants().forEach((p2) -> {
                    arrayList2.add(new Point(p2.getX1(), this.getTruePosition().y));
                });
                this.getMap().getCharacters().forEach((p2) -> {
                    arrayList2.add(new Point(p2.getPosition().x, this.getTruePosition().y));
                });
                arrayList2.forEach(point -> {
                            for (int i2 = 0; i2 < 2; ++i2) {
//                                Point point2 = new Point(Randomizer.rand(point.x - 600, point.x + 600), point.y);
//                                arrayList.add(point2);
                            }
                        }
                );
                String string;
                switch(type) {
                    case 1:
                        string = "DropPerifactionCurse";
                        break;
                    case 2:
                        string = "CapEffect";
                        break;
                    default:
                        return;
                }

                this.getMap().broadcastMessage(MaplePacketCreator.UserRequestChangeMobZoneState(string, arrayList));
            }

        }, 15000L);
    }




































    public final void applyMonsterBuff(final Map<MonsterStatus, Integer> effect, final int skillId, final long duration, final MobSkill skill, final List<Integer> reflection) {
        for (Map.Entry<MonsterStatus, Integer> z : effect.entrySet()) {
            if (mobEffects.containsKey(z.getKey())) {
                cancelStatus(z.getKey());
            }
            final MonsterStatusEffect effectz = new MonsterStatusEffect(z.getKey(), z.getValue(), 0, skill, true, reflection.size() > 0);
            effectz.setCancelTask(duration);
            mobEffects.put(z.getKey(), effectz);
        }
        final MapleCharacter con = getController();
        if (reflection.size() > 0) {
            List<MonsterStatusEffect> effects = new ArrayList<>();
            for (Map.Entry<MonsterStatus, Integer> z : effect.entrySet()) {
                effects.add(new MonsterStatusEffect(z.getKey(), z.getValue(), 0, skill, true, reflection.size() > 0));
            }
            this.reflectpack = MobPacket.applyMonsterStatus(this, effects);
            map.broadcastMessage(reflectpack, getTruePosition());
        } else {
            for (Map.Entry<MonsterStatus, Integer> z : effect.entrySet()) {
                MonsterStatusEffect mse = new MonsterStatusEffect(z.getKey(), z.getValue(), 0, skill, true, reflection.size() > 0);
                map.broadcastMessage(MobPacket.applyMonsterStatus(this, mse), getTruePosition());
            }
        }
    }



    public void setTempEffectiveness(Element e, long milli) {
        /* 1604 */
        this.stats.setEffectiveness(e, ElementalEffectiveness.虚弱);
        /* 1605 */
        EtcTimer.getInstance().schedule(() -> this.stats.removeEffectiveness(e), milli);

    }



    public boolean isBuffed(MonsterStatus status) {
        /* 1609 */
        if (status == MonsterStatus.MOB_STAT_Poison) {
            /* 1610 */
            return (this.poisonEffects.size() > 0 || this.mobEffects.containsKey(status));

        }
        /* 1612 */
        return this.mobEffects.containsKey(status);

    }



    public boolean isMyPoisons(MonsterStatus m2, int cid) {
        /* 1616 */
        for (MonsterStatusEffect o2 : this.poisonEffects) {
            /* 1617 */
            if (o2.getFromID() == cid) {
                /* 1618 */
                return true;

            }

        }
        /* 1621 */
        return false;

    }



    public MonsterStatusEffect getBuff(MonsterStatus status) {
        /* 1625 */
        return (MonsterStatusEffect) this.mobEffects.get(status);

    }



    public int getStatiSize() {
        /* 1629 */
        return this.mobEffects.size();

    }



    public ArrayList<MonsterStatusEffect> getAllBuffs() {
        /* 1633 */
        ArrayList<MonsterStatusEffect> ret = new ArrayList<>();
        /* 1634 */
        for (MonsterStatusEffect e : this.mobEffects.values()) {
            /* 1635 */
            ret.add(e);

        }
        /* 1637 */
        this.poisonsLock.readLock().lock();

        try {
            /* 1639 */
            for (MonsterStatusEffect e : this.poisonEffects) {
                /* 1640 */
                ret.add(e);

            }

        } finally {
            /* 1643 */
            this.poisonsLock.readLock().unlock();

        }
        /* 1645 */
        return ret;

    }



    public boolean isFake() {
        /* 1649 */
        return this.fake;

    }



    public void setFake(boolean fake) {
        /* 1653 */
        this.fake = fake;

    }



    public MapleMap getMap() {
        /* 1657 */
        return this.map;

    }



    public void setMap(MapleMap map) {
        /* 1661 */
        this.map = map;
        /* 1662 */
        startDropItemSchedule();

    }







    public final List<Pair<Integer, Integer>> getSkills() {
        /* 1670 */
        return this.stats.getSkills();

    }



    public boolean hasSkill(int skillId, int level) {
        /* 1674 */
        return this.stats.hasSkill(skillId, level);

    }



    public final long getLastSkillUsed(int skillId) {
        /* 1678 */
        if (this.usedSkills.containsKey(Integer.valueOf(skillId))) {
            /* 1679 */
            return ((Long) this.usedSkills.get(Integer.valueOf(skillId))).longValue();

        }
        /* 1681 */
        return 0L;

    }



    public final long getLastSkillUsed(int skillId, int skillLevel) {
        /* 1685 */
        for (Map.Entry<Pair<Integer, Integer>, Long> kvp : this.usedSkills.entrySet()) {
            /* 1686 */
            if (((Integer) ((Pair) kvp.getKey()).left).intValue() == skillId && ((Integer) ((Pair) kvp.getKey()).right).intValue() == skillLevel) {
                /* 1687 */
                return ((Long) kvp.getValue()).longValue();

            }

        }
        /* 1690 */
        return 0L;

    }












































    public final void setLastSkillUsed(int skillId, int skillLevel, long now, long cooltime) {
        /* 1735 */
        switch (skillId) {

            case 140:
                /* 1737 */
                this.usedSkills.put(new Pair(Integer.valueOf(skillId), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime * 2L));
                /* 1738 */
                this.usedSkills.put(new Pair(Integer.valueOf(141), Integer.valueOf(skillLevel)), Long.valueOf(now));

                return;

            case 141:
                /* 1741 */
                this.usedSkills.put(new Pair(Integer.valueOf(skillId), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime * 2L));
                /* 1742 */
                this.usedSkills.put(new Pair(Integer.valueOf(140), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime));

                return;

            case 143:
                /* 1745 */
                this.usedSkills.put(new Pair(Integer.valueOf(skillId), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime * 2L));
                /* 1746 */
                this.usedSkills.put(new Pair(Integer.valueOf(144), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime));
                /* 1747 */
                this.usedSkills.put(new Pair(Integer.valueOf(145), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime));

                return;

            case 144:
                /* 1750 */
                this.usedSkills.put(new Pair(Integer.valueOf(skillId), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime * 2L));
                /* 1751 */
                this.usedSkills.put(new Pair(Integer.valueOf(143), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime));
                /* 1752 */
                this.usedSkills.put(new Pair(Integer.valueOf(145), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime));

                return;

            case 145:
                /* 1755 */
                this.usedSkills.put(new Pair(Integer.valueOf(skillId), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime * 2L));
                /* 1756 */
                this.usedSkills.put(new Pair(Integer.valueOf(143), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime));
                /* 1757 */
                this.usedSkills.put(new Pair(Integer.valueOf(144), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime));

                return;

            case 228:
                /* 1760 */
                this.usedSkills.put(new Pair(Integer.valueOf(skillId), Integer.valueOf(skillLevel)), Long.valueOf(now + 30000L));

                return;

            case 238:
                /* 1763 */
                if (skillLevel == 5 || skillLevel == 10) {
                    /* 1764 */
                    this.usedSkills.put(new Pair(Integer.valueOf(skillId), Integer.valueOf(skillLevel)), Long.valueOf(now + 180000L));
                    /* 1765 */
                } else if (skillLevel == 9) {
                    /* 1766 */
                    this.usedSkills.put(new Pair(Integer.valueOf(skillId), Integer.valueOf(skillLevel)), Long.valueOf(now + 300000L));

                } else {
                    /* 1768 */
                    this.usedSkills.put(new Pair(Integer.valueOf(skillId), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime));

                }

                return;

        }
        /* 1772 */
        this.usedSkills.put(new Pair(Integer.valueOf(skillId), Integer.valueOf(skillLevel)), Long.valueOf(now + cooltime));

    }





    public byte getNoSkills() {
        /* 1778 */
        return this.stats.getNoSkills();

    }



    public boolean isFirstAttack() {
        /* 1782 */
        return this.stats.isFirstAttack();

    }



    public int getBuffToGive() {
        /* 1786 */
        return this.stats.getBuffToGive();

    }







    public void doPoison(MonsterStatusEffect status, WeakReference<MapleCharacter> weakChr) {
        /* 1794 */
        if (weakChr == null) {

            return;

        }
        /* 1797 */
        long damage = status.getPoisonSchedule();
        /* 1798 */
        boolean shadowWeb = (status.getSkill() == 4111003);
        /* 1799 */
        MapleCharacter chr = weakChr.get();
        /* 1800 */
        boolean cancel = (damage <= 0L || chr == null || chr.getMapId() != this.map.getId());
        /* 1801 */
        if (damage >= this.hp) {
            /* 1802 */
            damage = this.hp - 1L;
            /* 1803 */
            cancel = (!shadowWeb || cancel);

        }
        /* 1805 */
        if (!cancel) {
            /* 1806 */
            damage(chr, damage, false);
            /* 1807 */
            if (shadowWeb) {
                /* 1808 */
                this.map.broadcastMessage(MobPacket.damageMonster(getObjectId(), damage), getTruePosition());

            }

        }

    }



    public ConcurrentEnumMap<MonsterStatus, MonsterStatusEffect> getStati() {
        /* 1814 */
        return this.mobEffects;

    }



    public void addEmpty() {
        /* 1818 */
        for (MonsterStatus stat : MonsterStatus.values()) {
            /* 1819 */
            if (stat.isEmpty()) ;

        }

    }





    public int getStolen() {
        /* 1826 */
        return this.stolen;

    }



    public void setStolen(int s) {
        /* 1830 */
        this.stolen = s;

    }






    public void handleSteal(MapleCharacter chr) {
        /* 1837 */
        double showdown = 100.0D;
        /* 1838 */
        MonsterStatusEffect mse = getBuff(MonsterStatus.MOB_STAT_Showdown);
        /* 1839 */
        if (mse != null) {
            /* 1840 */
            showdown += mse.getX().intValue();

        }
        /* 1842 */
        Skill steal = SkillFactory.getSkill(4201004);
        /* 1843 */
        int level = chr.getTotalSkillLevel(steal), chServerrate = ChannelServer.getInstance(chr.getClient().getChannel()).getDropRate();
        /* 1844 */
        if (level > 0 && !isBoss() && this.stolen == -1 && steal.getEffect(level).makeChanceResult()) {
            /* 1845 */
            MapleMonsterInformationProvider mi = MapleMonsterInformationProvider.getInstance();
            /* 1846 */
            List<MonsterDropEntry> de = (List<MonsterDropEntry>) mi.retrieveDrop(getId()).stream().collect(Collectors.toList());
            /* 1847 */
            if (de.isEmpty()) {
                /* 1848 */
                this.stolen = 0;

                return;

            }
            /* 1851 */
            Collections.shuffle(de);
            /* 1852 */
            double finalShowdown = showdown;
            /* 1853 */
            de.parallelStream().filter(d -> (d.itemId > 0 && d.questid == 0 && d.itemId / 10000 != 238 && Randomizer.nextInt(999999) < (int) ((10 * d.chance * chServerrate * chr.getDropMod()) * chr.getStat().getDropBuff() / 100.0D * finalShowdown / 100.0D)))
/* 1854 */.forEach(d -> {

                Item idrop=null;

                if (ItemConstants.getInventoryType(d.itemId) == MapleInventoryType.EQUIP) {

                    Equip eq = (Equip) MapleItemInformationProvider.getInstance().getEquipById(d.itemId);

                    Equip equip1 = MapleItemInformationProvider.getInstance().randomizeStats(eq);

                } else {

                    idrop = new Item(d.itemId, (short) 0, (short) ((d.maximum != 1) ? (Randomizer.nextInt(d.maximum - d.minimum) + d.minimum) : 1), (short) 0);

                }

                this.stolen = d.itemId;

                this.map.spawnMobDrop(idrop, this.map.calcDropPos(getPosition(), getTruePosition()), this, chr, (byte) 0, 0);

            });

        } else {
            /* 1866 */
            this.stolen = 0;

        }

    }






    public void cancelStatus(MonsterStatus stat) {
        /* 1874 */
        if (stat == MonsterStatus.MOB_STAT_Treasure || stat == MonsterStatus.MOB_STAT_ExchangeAttack || stat == MonsterStatus.MOB_STAT_Laser) {

            return;

        }
        /* 1877 */
        MonsterStatusEffect mse = (MonsterStatusEffect) this.mobEffects.get(stat);
        /* 1878 */
        if (mse == null || !isAlive()) {

            return;

        }
        /* 1881 */
        if (mse.isReflect()) {
            /* 1882 */
            this.reflectpack = null;

        }
        /* 1884 */
        mse.cancelPoisonSchedule(this);
        /* 1885 */
        MapleCharacter con = getController();
        /* 1886 */
        if (con != null) {
            /* 1887 */
            this.map.broadcastMessage(con, MobPacket.cancelMonsterStatus(this, mse), getTruePosition());
            /* 1888 */
            con.getClient().announce(MobPacket.cancelMonsterStatus(this, mse));

        } else {
            /* 1890 */
            this.map.broadcastMessage(MobPacket.cancelMonsterStatus(this, mse), getTruePosition());

        }
        /* 1892 */
        if (this.mobEffects.isEmpty()) {
            /* 1893 */
            this.mobEffects.replace(stat, new MonsterStatusEffect(stat, Integer.valueOf(0), 0, null, false));

        }

        /* 1896 */
        this.mobEffects.remove(stat);

    }






    public void cancelSingleStatus(MonsterStatusEffect stat) {
        /* 1903 */
        if (stat == null || stat.getStati() == MonsterStatus.MOB_STAT_Treasure || stat.getStati() == MonsterStatus.MOB_STAT_ExchangeAttack || !isAlive()) {

            return;

        }
        /* 1906 */
        if (stat.getStati() != MonsterStatus.MOB_STAT_Poison) {
            /* 1907 */
            cancelStatus(stat.getStati());

            return;

        }
        /* 1910 */
        this.poisonsLock.writeLock().lock();

        try {
            /* 1912 */
            if (!this.poisonEffects.contains(stat)) {

                return;

            }
            /* 1915 */
            this.poisonEffects.remove(stat);
            /* 1916 */
            if (stat.isReflect()) {
                /* 1917 */
                this.reflectpack = null;

            }

            /* 1920 */
            MapleCharacter con = getController();
            /* 1921 */
            if (con != null) {
                /* 1922 */
                this.map.broadcastMessage(con, MobPacket.cancelMonsterStatus(this, stat), getTruePosition());
                /* 1923 */
                con.getClient().announce(MobPacket.cancelMonsterStatus(this, stat));

            } else {
                /* 1925 */
                this.map.broadcastMessage(MobPacket.cancelMonsterStatus(this, stat), getTruePosition());

            }
            /* 1927 */
            stat.cancelPoisonSchedule(this);

        } finally {
            /* 1929 */
            this.poisonsLock.writeLock().unlock();

        }

    }



    public int getLinkOid() {
        /* 1934 */
        return this.linkoid;

    }



    public void setLinkOid(int lo) {
        /* 1938 */
        this.linkoid = lo;

    }



    public int getLastNode() {
        /* 1942 */
        return this.lastNode;

    }



    public void setLastNode(int lastNode) {
        /* 1946 */
        this.lastNode = lastNode;

    }



    public void cancelDropItem() {
        /* 1950 */
        this.lastDropTime = 0L;

    }



    public void startDropItemSchedule() {
        /* 1954 */
        cancelDropItem();
        /* 1955 */
        if (this.stats.getDropItemPeriod() <= 0 || !isAlive()) {

            return;

        }
        /* 1958 */
        this.shouldDropItem = false;
        /* 1959 */
        this.lastDropTime = System.currentTimeMillis();

    }



    public boolean shouldDrop(long now) {
        /* 1963 */
        return (this.lastDropTime > 0L && this.lastDropTime + (this.stats.getDropItemPeriod() * 1000) < now);

    }



    public boolean checkLastMove() {
        /* 1967 */
        return (System.currentTimeMillis() - this.lastMove > 8000L && this.lastMove > 0L);

    }



    public void setLastMove() {
        /* 1971 */
        this.lastMove = System.currentTimeMillis();

    }



    public void doDropItem(long now) {

        int itemId;
        /* 1976 */
        switch (getId()) {

            case 9300061:
                /* 1978 */
                itemId = 4001101;

                break;

            default:
                /* 1981 */
                cancelDropItem();

                return;

        }
        /* 1984 */
        if (isAlive() && this.map != null) {
            /* 1985 */
            if (this.shouldDropItem) {
                /* 1986 */
                this.map.spawnAutoDrop(itemId, getTruePosition());

            } else {
                /* 1988 */
                this.shouldDropItem = true;

            }

        }
        /* 1991 */
        this.lastDropTime = now;

    }



    public byte[] getNodePacket() {
        /* 1995 */
        return this.nodepack;

    }



    public void setNodePacket(byte[] np) {
        /* 1999 */
        this.nodepack = np;

    }



    public void registerKill(long next) {
        /* 2003 */
        this.nextKill = System.currentTimeMillis() + next;

    }



    public boolean shouldKill(long now) {
        /* 2007 */
        return (this.nextKill > 0L && now > this.nextKill);

    }



    public int getLinkCID() {
        /* 2011 */
        return this.linkCID;

    }



    public void setLinkCID(int lc) {
        /* 2015 */
        this.linkCID = lc;
        /* 2016 */
        if (lc > 0) ;

    }





    public int getMobFH() {
        /* 2022 */
        MapleFoothold fh = getMap().getFootholds().findBelow(getTruePosition(), true);
        /* 2023 */
        if (fh != null) {
            /* 2024 */
            return fh.getId();

        }
        /* 2026 */
        return 0;

    }



    public Map<String, Integer> getAggroRank() {
        /* 2030 */
        return this.aggroRank;

    }



    public List<Rectangle> getRectangles() {
        /* 2034 */
        return this.rectangles;

    }



    public void setRectangles(List<Rectangle> rectangles) {
        /* 2038 */
        this.rectangles = rectangles;

    }










    /**
     * *
     * 获取怪物Buff的列表(用于进行排列)
     *
     * @param mobEffect
     * @return
     */
    public ConcurrentEnumMap<MonsterStatus, MonsterStatusEffect> ArrayMonsterStatus(ConcurrentEnumMap<MonsterStatus, MonsterStatusEffect> mobEffect) {
        ConcurrentEnumMap<MonsterStatus, MonsterStatusEffect> mList = new ConcurrentEnumMap<>(MonsterStatus.class);//new LinkedList<MonsterStatus>();
        for (Map.Entry<MonsterStatus, MonsterStatusEffect> status : mobEffect.entrySet()) {
            mList.put(status.getKey(), status.getValue());//.add(status);
        }

        return mList;
    }





    /*
     * 给怪物单个的BUFF状态
     */
    public void applyStatus(MonsterStatusEffect status) {
        if (mobEffects.containsKey(status.getStati())) {
            cancelStatus(status.getStati());
        }
        mobEffects.put(status.getStati(), status);
        map.broadcastMessage(MobPacket.applyMonsterStatus(this, status), getTruePosition());
    }



    public int getTriangulation() {
        /* 2069 */
        return this.triangulation;

    }



    public void setTriangulation(int triangulation) {
        /* 2073 */
        this.triangulation = triangulation;

    }



    public int getPatrolScopeX1() {
        /* 2077 */
        return this.patrolScopeX1;

    }



    public void setPatrolScopeX1(int patrolScopeX1) {
        /* 2081 */
        this.patrolScopeX1 = patrolScopeX1;

    }



    public int getPatrolScopeX2() {
        /* 2085 */
        return this.patrolScopeX2;

    }



    public void setPatrolScopeX2(int patrolScopeX2) {
        /* 2089 */
        this.patrolScopeX2 = patrolScopeX2;

    }







       private static class AttackingMapleCharacter
             {
             private final MapleCharacter attacker;





             private final long lastAttackTime;







        public AttackingMapleCharacter(MapleCharacter attacker, long lastAttackTime) {
            /* 2112 */
            this.attacker = attacker;
            /* 2113 */
            this.lastAttackTime = lastAttackTime;

        }



        public long getLastAttackTime() {
            /* 2117 */
            return this.lastAttackTime;

        }






        public MapleCharacter getAttacker() {
            /* 2124 */
            return this.attacker;

        }

    }



       private static final class OnePartyAttacker
             {
             public MapleParty lastKnownParty;
             public long damage;
             public long lastAttackTime;



        public OnePartyAttacker(MapleParty lastKnownParty, long damage) {
            /* 2136 */
            this.lastKnownParty = lastKnownParty;
            /* 2137 */
            this.damage = damage;
            /* 2138 */
            this.lastAttackTime = System.currentTimeMillis();

        }

    }


       private final class SingleAttackerEntry
             implements AttackerEntry {
             private final int chrid;
        /* 2145 */     private long damage = 0L;
             private long lastAttackTime;



        public SingleAttackerEntry(MapleCharacter from) {
            /* 2149 */
            this.chrid = from.getId();

        }




        public void addDamage(MapleCharacter from, long damage, boolean updateAttackTime) {
            /* 2154 */
            if (this.chrid == from.getId()) {
                /* 2155 */
                this.damage += damage;
                /* 2156 */
                if (updateAttackTime) {
                    /* 2157 */
                    this.lastAttackTime = System.currentTimeMillis();

                }

            }

        }




        public List<MapleMonster.AttackingMapleCharacter> getAttackers() {
            /* 2164 */
            MapleCharacter chr = MapleMonster.this.map.getCharacterById(this.chrid);
            /* 2165 */
            if (chr != null) {
                /* 2166 */
                return Collections.singletonList(new MapleMonster.AttackingMapleCharacter(chr, this.lastAttackTime));

            }
            /* 2168 */
            return Collections.emptyList();

        }





        public boolean contains(MapleCharacter chr) {
            /* 2174 */
            return (this.chrid == chr.getId());

        }




        public long getDamage() {
            /* 2179 */
            return this.damage;

        }




        public void killedMob(MapleMap map, int baseExp, boolean mostDamage, int lastSkill) {
            /* 2184 */
            MapleCharacter chr = map.getCharacterById(this.chrid);
            /* 2185 */
            if (chr != null && chr.isAlive()) {
                /* 2186 */
                MapleMonster.this.giveExpToCharacter(chr, baseExp, mostDamage, 1, lastSkill);

            }

        }




        public int hashCode() {
            /* 2192 */
            return this.chrid;

        }




        public boolean equals(Object obj) {
            /* 2197 */
            if (this == obj) {
                /* 2198 */
                return true;

            }
            /* 2200 */
            if (obj == null) {
                /* 2201 */
                return false;

            }
            /* 2203 */
            if (getClass() != obj.getClass()) {
                /* 2204 */
                return false;

            }
            /* 2206 */
            SingleAttackerEntry other = (SingleAttackerEntry) obj;
            /* 2207 */
            return (this.chrid == other.chrid);

        }

    }


       private class PartyAttackerEntry
             implements AttackerEntry {
        /* 2213 */     private final Map<Integer, MapleMonster.OnePartyAttacker> attackers = new HashMap<>(6);
             private final int partyid;
        /* 2215 */     private long totDamage = 0L;



        public PartyAttackerEntry(int partyid) {
            /* 2218 */
            this.partyid = partyid;

        }




        public List<MapleMonster.AttackingMapleCharacter> getAttackers() {
            /* 2223 */
            List<MapleMonster.AttackingMapleCharacter> ret = new ArrayList<>(this.attackers.size());
            /* 2224 */
            for (Map.Entry<Integer, MapleMonster.OnePartyAttacker> entry : this.attackers.entrySet()) {
                /* 2225 */
                MapleCharacter chr = MapleMonster.this.map.getCharacterById(((Integer) entry.getKey()).intValue());
                /* 2226 */
                if (chr != null) {
                    /* 2227 */
                    ret.add(new MapleMonster.AttackingMapleCharacter(chr, ((MapleMonster.OnePartyAttacker) entry.getValue()).lastAttackTime));

                }

            }
            /* 2230 */
            return ret;

        }



        private Map<MapleCharacter, MapleMonster.OnePartyAttacker> resolveAttackers() {
            /* 2234 */
            Map<MapleCharacter, MapleMonster.OnePartyAttacker> ret = new HashMap<>(this.attackers.size());
            /* 2235 */
            for (Map.Entry<Integer, MapleMonster.OnePartyAttacker> aentry : this.attackers.entrySet()) {
                /* 2236 */
                MapleCharacter chr = MapleMonster.this.map.getCharacterById(((Integer) aentry.getKey()).intValue());
                /* 2237 */
                if (chr != null) {
                    /* 2238 */
                    ret.put(chr, aentry.getValue());

                }

            }
            /* 2241 */
            return ret;

        }




        public boolean contains(MapleCharacter chr) {
            /* 2246 */
            return this.attackers.containsKey(Integer.valueOf(chr.getId()));

        }




        public long getDamage() {
            /* 2251 */
            return this.totDamage;

        }




        public void addDamage(MapleCharacter from, long damage, boolean updateAttackTime) {
            /* 2256 */
            MapleMonster.OnePartyAttacker oldPartyAttacker = this.attackers.get(Integer.valueOf(from.getId()));
            /* 2257 */
            if (oldPartyAttacker != null) {
                /* 2258 */
                oldPartyAttacker.damage += damage;
                /* 2259 */
                oldPartyAttacker.lastKnownParty = from.getParty();
                /* 2260 */
                if (updateAttackTime) {
                    /* 2261 */
                    oldPartyAttacker.lastAttackTime = System.currentTimeMillis();


                }


            }

            else {

                /* 2268 */
                MapleMonster.OnePartyAttacker onePartyAttacker = new MapleMonster.OnePartyAttacker(from.getParty(), damage);
                /* 2269 */
                this.attackers.put(Integer.valueOf(from.getId()), onePartyAttacker);
                /* 2270 */
                if (!updateAttackTime) {
                    /* 2271 */
                    onePartyAttacker.lastAttackTime = 0L;

                }

            }
            /* 2274 */
            this.totDamage += damage;

        }




        public void killedMob(MapleMap map, int baseExp, boolean mostDamage, int lastSkill) {
            /* 2279 */
            MapleCharacter highest = null;
            /* 2280 */
            long highestDamage = 0L;



            /* 2284 */
            Map<MapleCharacter, Integer> expMap = new HashMap<>(6);

            /* 2286 */
            for (Map.Entry<MapleCharacter, MapleMonster.OnePartyAttacker> attacker : resolveAttackers().entrySet()) {
                /* 2287 */
                MapleParty party = ((MapleMonster.OnePartyAttacker) attacker.getValue()).lastKnownParty;
                /* 2288 */
                double addedPartyLevel = 0.0D;
                /* 2289 */
                List<MapleCharacter> expApplicable = new ArrayList<>();
                /* 2290 */
                for (MaplePartyCharacter partychar : party.getMembers()) {
                    /* 2291 */
                    if (((MapleCharacter) attacker.getKey()).getLevel() - partychar.getLevel() <= 5 || MapleMonster.this.stats.getLevel() - partychar.getLevel() <= 5) {
                        /* 2292 */
                        MapleCharacter pchr = map.getCharacterById(partychar.getId());
                        /* 2293 */
                        if (pchr != null && pchr.isAlive() && pchr.getMap() == map) {
                            /* 2294 */
                            expApplicable.add(pchr);
                            /* 2295 */
                            addedPartyLevel += pchr.getLevel();

                        }

                    }

                }
                /* 2299 */
                double expBonus = 1.0D;
                /* 2300 */
                if (expApplicable.size() > 1) {
                    /* 2301 */
                    expBonus = 1.1D + 0.05D * expApplicable.size();
                    /* 2302 */
                    addedPartyLevel /= expApplicable.size();

                }
                /* 2304 */
                long iDamage = ((MapleMonster.OnePartyAttacker) attacker.getValue()).damage;
                /* 2305 */
                if (iDamage > highestDamage) {
                    /* 2306 */
                    highest = attacker.getKey();
                    /* 2307 */
                    highestDamage = iDamage;

                }
                /* 2309 */
                double innerBaseExp = baseExp * iDamage / this.totDamage;
                /* 2310 */
                double expFraction = innerBaseExp * expBonus / (expApplicable.size() + 1);

                /* 2312 */
                for (MapleCharacter expReceiver : expApplicable) {
                    /* 2313 */
                    int iexp;
                    Integer oexp = expMap.get(expReceiver);

                    /* 2315 */
                    if (oexp == null) {
                        /* 2316 */
                        iexp = 0;

                    } else {
                        /* 2318 */
                        iexp = oexp.intValue();

                    }
                    /* 2320 */
                    double expWeight = (expReceiver == attacker.getKey()) ? 2.0D : 1.0D;
                    /* 2321 */
                    double levelMod = expReceiver.getLevel() / addedPartyLevel;
                    /* 2322 */
                    if (levelMod > 1.0D || this.attackers.containsKey(Integer.valueOf(expReceiver.getId()))) {
                        /* 2323 */
                        levelMod = 1.0D;

                    }
                    /* 2325 */
                    iexp += (int) Math.round(expFraction * expWeight * levelMod);
                    /* 2326 */
                    expMap.put(expReceiver, Integer.valueOf(iexp));

                }

            }
            /* 2329 */
            for (Map.Entry<MapleCharacter, Integer> expReceiver : expMap.entrySet()) {
                /* 2330 */
                MapleMonster.this.giveExpToCharacter(expReceiver.getKey(), ((Integer) expReceiver.getValue()).intValue(), (mostDamage && expReceiver.getKey() == highest), expMap.size(), lastSkill);

            }

        }




        public int hashCode() {
            /* 2336 */
            int prime = 31;
            /* 2337 */
            int result = 1;
            /* 2338 */
            result = prime * result + this.partyid;
            /* 2339 */
            return result;

        }




        public boolean equals(Object obj) {
            /* 2344 */
            if (this == obj) {
                /* 2345 */
                return true;

            }
            /* 2347 */
            if (obj == null) {
                /* 2348 */
                return false;

            }
            /* 2350 */
            if (getClass() != obj.getClass()) {
                /* 2351 */
                return false;

            }
            /* 2353 */
            PartyAttackerEntry other = (PartyAttackerEntry) obj;
            /* 2354 */
            return (this.partyid == other.partyid);

        }

    }


       private static interface AttackerEntry {
             List<MapleMonster.AttackingMapleCharacter> getAttackers();


             void addDamage(MapleCharacter param1MapleCharacter, long param1Long, boolean param1Boolean);


             long getDamage();


             boolean contains(MapleCharacter param1MapleCharacter);


             void killedMob(MapleMap param1MapleMap, int param1Int1, boolean param1Boolean, int param1Int2);

    }

}


/* Location:              C:\PGX\Server.jar!\server\life\MapleMonster.class
 * Java compiler version: 8 (52.0)
 * JD-Core Version:       1.1.3
 */